home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
intrvews
/
xgrab.lha
/
xgrab
/
ui
/
routines2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-06
|
9KB
|
444 lines
/**
GRAB Graph Layout and Browser System
Copyright (c) 1986, 1988 Regents of the University of California
Copyright (c) 1989, Tera Computer Company
**/
/**
routines2.c -- more fun menu routines, including most of the
statistics dumping routines and the checkpoint routines
**/
#include "malloc.h"
#include <math.h>
#include "attribute.h"
#include "digraph.h"
#include "screen.h"
#include "globals.h"
#include "scrdep.h"
#include "interf.h"
#include "checkpoint.h"
#include "cursor.h"
extern NODE *next_dummy();
void DoPrintDistributionStats();
DumpBox(b)
BOX *b;
{
printf("min_x=%d, max_x=%d, min_y=%d, max_y=%d",
b->min_x, b->max_x, b->min_y, b->max_y);
}
/**
For button area.
Can't press buttons while moving or inserting.
Can press button while changing labels (just leave the current mode)
**/
BOOL GetInCTextModeFlag()
{
return (inChangeTextMode);
}
BOOL GetInCEdgeLabelModeFlag()
{
return (inChangeEdgeLabelMode);
}
BOOL GetInFNodeModeFlag()
{
return (inFocusNodeMode);
}
BOOL GetInCModeFlag()
{
return (inChangeTextMode || inChangeEdgeLabelMode || inFocusNodeMode);
}
void ClearInModeFlag()
{
inChangeTextMode = FALSE;
inChangeEdgeLabelMode = FALSE;
inFocusNodeMode = FALSE;
}
void DoPrintLayoutStats()
{
printf("\n*XGRAB LAYOUT STATS*\n");
PrintNodeStats();
PrintEdgeStats();
PrintLevelStats();
PrintCrossingsStats();
DoPrintDistributionStats();
PrintAbsCoordStats();
}
PrintNodeStats()
{
NODE *node;
int dummyNodeCount, realNodeCount;
dummyNodeCount = realNodeCount = 0;
each_node(digraph, node)
loop
if (Is_dummy(node))
{
dummyNodeCount++;
}
else
{
realNodeCount++;
}
endloop
printf("total # of nodes: %d (real=%d;dummy=%d)\n",
dummyNodeCount+realNodeCount, realNodeCount, dummyNodeCount);
}
Length(fromMember, toMember)
MEMBER *fromMember, *toMember;
{
int xdist, ydist, dist;
xdist = X_position(fromMember) - X_position(toMember);
ydist = Y_position(fromMember) - Y_position(toMember);
dist = (xdist * xdist) + (ydist * ydist);
return((int) sqrt((double) dist));
};
PrintEdgeStats()
{
VNO toVno; /* each succedent node */
NODE *node, *toNode;
int totalEdgeCount, shortEdgeCount, longEdgeCount, segmentCount;
int totalEdgeLength;
totalEdgeCount = shortEdgeCount = longEdgeCount = segmentCount = 0;
totalEdgeLength = 0;
each_node(digraph, node)
loop
if (Is_dummy(node))
{
continue;
}
each_element(Succ_set(node), toVno)
loop
toNode = Node(digraph, toVno);
totalEdgeCount++;
totalEdgeLength += Length(Node_member(node), Node_member(toNode));
if (!Is_dummy(toNode))
{
shortEdgeCount++;
segmentCount++;
}
else
{
longEdgeCount++;
segmentCount++;
toNode = next_dummy(digraph, node);
while (Is_dummy(toNode))
{
segmentCount++;
totalEdgeLength += Length(Node_member(node),
Node_member(toNode));
toNode = next_dummy(digraph, toNode);
}
segmentCount++;
totalEdgeLength += Length(Node_member(node),
Node_member(toNode));
}
endloop
endloop
printf("total # of edges: %d (short: %d, long: %d)\n", totalEdgeCount,
shortEdgeCount, longEdgeCount);
printf("total segments: %d\n", segmentCount);
printf("total edge length: %d\n", totalEdgeLength);
}
#define MAX_LEV_ARRAY 512
PrintLevelStats()
{
int i, count = 0;
LEVEL *level;
MEMBER *member;
double stdDev, mean, sum, diff;
int maxLevelCoord, median, levArray[MAX_LEV_ARRAY];
if (!digraph->levels)
{
printf("level stats unavailable - no level structure\n");
return;
}
each_level(digraph, level)
loop
each_member(level, member)
loop
if (count < MAX_LEV_ARRAY)
{
levArray[count++] = Y_position(member);
}
else
{
fprintf(stderr, "PrintLevelStats: outa room in levArray\n");
}
break;
endloop
endloop
/* calc maxLevelCoord */
maxLevelCoord = levArray[0];
/* calc median */
median = levArray[(count-1)/2];
/* calc mean */
sum = 0.0;
for (i = 0; i < count; i++)
{
sum += levArray[i];
}
mean = sum/(double)count;
/* calc std dev */
sum = 0.0;
for (i = 0; i < count; i++)
{
diff = (double)levArray[i] - mean;
sum += diff * diff;
}
sum = sum / (double) count;
stdDev = sqrt(sum);
printf("# levels = %d; ", count);
printf("max = %d; median = %d; mean = %.2f; std dev = %.2f\n",
maxLevelCoord, median, mean, stdDev);
}
PrintCrossingsStats()
{
if (!digraph->levels)
{
printf("crossings stats is unavailable - no level structure\n");
}
else
{
printf("# of edge crossings = %d\n", num_crossings(digraph));
}
}
#define MAX_XBINS 4
#define MAX_YBINS 4
void DoPrintDistributionStats()
{
BOX absView;
NODE *node;
int bins[MAX_XBINS][MAX_YBINS];
int num_xbins, num_ybins, xbin, ybin, count, i, j;
float xDiv, yDiv, mean, diff, variance;
printf("Node Spatial Distribution:\n");
FindRange(digraph, &absView);
for (num_xbins = 1, num_ybins = 1;
num_xbins <= MAX_XBINS && num_ybins <= MAX_YBINS;
num_xbins++, num_ybins++)
{
xDiv = (absView.max_x - absView.min_x) / (float) num_xbins;
yDiv = (absView.max_y - absView.min_y) / (float) num_ybins;
count = 0;
for (i = 0; i < num_xbins; i++)
{
for (j = 0; j < num_ybins; j++)
{
bins[i][j] = 0;
}
}
each_node(digraph, node)
loop
if (!Is_dummy(node))
{
/*
* Compute the bin this node falls into, and increment count.
*/
xbin = (X_position(Node_member(node)) - absView.min_x) / xDiv;
ybin = (Y_position(Node_member(node)) - absView.min_y) / yDiv;
bins[xbin][ybin]++;
count++;
}
endloop
/*
* Calculate mean and variance for bins entries.
*/
mean = (float) count / (num_xbins * num_ybins);
variance = 0.0;
for (i = 0; i < num_xbins; i++)
{
for (j = 0; j < num_ybins; j++)
{
diff = (float) bins[i][j] - mean;
variance += diff * diff;
}
}
variance = variance / (num_xbins * num_ybins);
printf("\t%d x %d bins, Var = %5.2f\n", num_xbins, num_ybins, variance);
}
} /* DoPrintDistributionStats */
PrintAbsCoordStats()
{
BOX absView;
FindRange(digraph, &absView);
printf("absolute view bounding box: min_x=%d, min_y=%d, max_x=%d, max_y=%d\n",
absView.min_x, absView.min_y, absView.max_x, absView.max_y);
}
void DoDumpNodeList()
{
NODE *node;
each_node(digraph, node)
loop
DumpNode(node);
endloop
}
DumpNode(node)
NODE *node;
{
printf("node=/%s/; vno=%d; x_pos=%d; y_pos=%d\n",
Text(node), Vno(node), X_position(node), Y_position(node));
}
DIGRAPH* copy_digraph();
DoSaveCkpt()
{
int i;
char *buf;
buf = (char *) malloc(sizeof(char) * MAXLINE);
IChangeStatusLine("Saving current graph", TRUE);
for (i = curr_ckpt + 1; i < num_ckpts; i++)
{
dispose_digraph(ckpts[i]->digraph);
dispose(ckpts[i]);
}
create_checkpoint();
sprintf(buf, "Saved as checkpoint #%d", num_ckpts);
IChangeStatusLine(buf, FALSE);
ckpt_done = TRUE;
dispose(buf);
}
create_checkpoint()
{
curr_ckpt++;
num_ckpts = curr_ckpt + 1;
if (num_ckpts != 1)
{
ckpts = (CHECKPT **) realloc((char *) ckpts,
num_ckpts * sizeof(CHECKPT *));
}
else
{
ckpts = (CHECKPT **) malloc(sizeof(CHECKPT *));
}
new(ckpts[curr_ckpt], CHECKPT);
ckpts[curr_ckpt]->digraph = copy_digraph(digraph);
}
DoPrevCkpt()
{
char *buf;
buf = (char *) malloc(sizeof(char) * MAXLINE);
IChangeStatusLine("Going to previous checkpoint", TRUE);
ISetCursor(waitC);
if (curr_ckpt > 0 || !ckpt_done && curr_ckpt == 0)
{
/* if we've changed the graph since the last checkpoint, just go back
to the current one, otherwise, go back one */
if (ckpt_done)
{
curr_ckpt--;
}
dispose_digraph(digraph);
digraph = copy_digraph(ckpts[curr_ckpt]->digraph);
DisplayNewGraph();
sprintf(buf, "Now at checkpoint #%d", curr_ckpt + 1);
IChangeStatusLine(buf, FALSE);
ckpt_done = TRUE;
}
else
{
IChangeStatusLine("No checkpoints before this one.", FALSE);
}
IUnsetCursor();
dispose(buf);
}
DoNextCkpt()
{
char *buf;
buf = (char *) malloc(sizeof(char) * MAXLINE);
IChangeStatusLine("Going to next checkpoint", TRUE);
ISetCursor(waitC);
if (curr_ckpt + 1 < num_ckpts)
{
curr_ckpt++;
dispose_digraph(digraph);
digraph = copy_digraph(ckpts[curr_ckpt]->digraph);
DisplayNewGraph();
sprintf(buf, "Now at checkpoint #%d", curr_ckpt + 1);
IChangeStatusLine(buf, FALSE);
ckpt_done = TRUE;
}
else
{
IChangeStatusLine("No checkpoints after this one.", FALSE);
}
IUnsetCursor();
dispose(buf);
}
double GetAspRatio()
{
return (double) aspratio;
}